#pragma once
#include <memory>
#include <map>
#include <vector>
#include <mutex>
#include <string>

#include "mixer/AudioScenesInItem.h"
#include "mixer/VideoScenesInItem.h"
#include "mixer/AudioScenesOutItem.h"
#include "mixer/VideoScenesOutItem.h"
#include "mixer/VideoMixerManager.h"
#include "mixer/AudioMixerManager.h"
#include "source/output/OutputSourceManager.h"


namespace Media{

    [[maybe_unused]] typedef struct{
        std::string m_name;
        std::map<uint32_t, VideoScenesInItemConfig> m_vInConfig;
        std::map<uint32_t, AudioScenesInItemConfig> m_aInConfig;
        VideoScenesOutItemConfig m_vOutConfig;
        AudioScenesOutItemConfig m_aOutConfig;
        std::vector<uint32_t> m_vOutSources;
        std::vector<uint32_t> m_aOutSources;
    }ScenesConfig;


    class Scenes{
    public:
        using ItemId = uint32_t;
        using Ptr = std::shared_ptr<Scenes>;
        explicit Scenes(std::string  name);
        ~Scenes(); 

        const std::string& GetName();
        // In Item Operate
        bool AddVideoInItem(const ItemId& id, const VideoScenesInItemConfig& config);
        bool AddAudioInItem(const ItemId& id, const AudioScenesInItemConfig& config);
        bool SetVideoInItem(const ItemId& id, const VideoScenesInItemConfig& config);
        bool SetAudioInItem(const ItemId& id, const AudioScenesInItemConfig& config);
        std::map<ItemId, VideoScenesInItemConfig> GetAllVideoInItem();
        bool GetVideoInItem(const ItemId& id, VideoScenesInItemConfig& config);
        std::map<ItemId, AudioScenesInItemConfig> GetAllAudioInItem();
        bool GetAudioInItem(const ItemId& id, AudioScenesInItemConfig& config);
        bool DelVideoInItem(const ItemId& id);
        bool DelAudioInItem(const ItemId& id);

        // Out Item Operate
        bool SetVideoOutConfig(const VideoScenesOutItemConfig& config);
        bool SetAudioOutConfig(const AudioScenesOutItemConfig& config);
        bool GetVideoOutConfig(VideoScenesOutItemConfig& config);
        bool GetAudioOutConfig(AudioScenesOutItemConfig& config);
        bool AddVideoOutSource(OutputSource::OutputSourceId id,const std::string& name); 
        bool AddAudioOutSource(OutputSource::OutputSourceId id,const std::string& name); 
        bool RemoveVideoOutSource(OutputSource::OutputSourceId id);
        bool RemoveAudioOutSource(OutputSource::OutputSourceId id);

        bool SetFrameOutCb(const std::function<void (const FrameCommon::Frame::Ptr&)>& cb);

        bool Start();
        bool IsRunning();
        bool Stop();

    private:
        bool m_running;
        std::string m_name;
        std::recursive_mutex m_mux;

        VideoMixer::Ptr m_videoMixer;
        AudioMixer::Ptr m_audioMixer;
    };
}